package alexattar.gdxtest.screens.scene2d;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import sun.java2d.pipe.RegionIterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Input.Peripheral;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Array;
import com.sun.corba.se.spi.ior.iiop.MaxStreamFormatVersionComponent;

import alexattar.gdxtest.GdxTestGame;
import alexattar.gdxtest.Ship;
import alexattar.gdxtest.screens.AbstractScreen;

public class Ship2D extends Image {
	private static final float MAX_SPEED = (AbstractScreen.GAME_VIEWPORT_WIDTH / 1.5f);
	private static final float MAX_ACCELERATION = 8f;
	private static final float MAX_DECELERATION = MAX_ACCELERATION / 2f;
	
	private final Animation tiltAnimation;
	private float tiltAnimationStateTime;
	
	private Vector2 position;
	private Vector2 velocity;
	private Vector2 acceleration;
	
	private Map<TextureRegion, Drawable> tiltAnimationDrawables;
	
	public static Ship2D create(Ship ship, TextureAtlas textureAtlas) {
		String prefix = "level-screen/";
		Array<AtlasRegion> regions = textureAtlas.findRegions(prefix + ship.getShipModel().getSimpleName());
		Iterator<AtlasRegion> regionIterator = regions.iterator();
		while(regionIterator.hasNext()) {
			if (regionIterator.next().index < 0) {
				regionIterator.remove();
			}
		}
		Ship2D ship2d = new Ship2D(ship, regions);
		return ship2d;
	}
	
	private Ship2D(Ship ship, Array<AtlasRegion> tiltAnimationFrames) {
		super(tiltAnimationFrames.get(0));
		super.setTouchable(Touchable.disabled);
		this.acceleration = new Vector2();
		this.velocity = new Vector2();
		this.position = new Vector2();
		
		this.tiltAnimation = new Animation(0.15f, tiltAnimationFrames);
		this.tiltAnimationDrawables = new HashMap<TextureRegion, Drawable>();
		for(AtlasRegion region : tiltAnimationFrames) {
			tiltAnimationDrawables.put(region, new TextureRegionDrawable(region));
		}
		
	}
	
	@Override
	public void act(float delta) {
		super.act(delta);
		moveShip(delta);
		tiltShip(delta);
	}
	
	private void moveShip(float delta) {
		position.set(getX(), getY());
		if (Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer)) {
			if (GdxTestGame.DEV_MODE) {
				Gdx.app.debug(GdxTestGame.LOG, 
						Gdx.input.getAccelerometerX() + "," + 
						Gdx.input.getAccelerometerY() + "," +
						Gdx.input.getAccelerometerZ());
			}
			
//			float adjustedX = Gdx.input.getAccelerometerX() - 2f;
//			if (adjustedX < -2f) adjustedX = -2f;
//			else if(adjustedX > 2f) adjustedX = 2f;
//			
//			float adjustedY = Gdx.input.getAccelerometerX();
//			if (adjustedY < -2f) adjustedY = -2f;
//			else if(adjustedY > 2f) adjustedY = 2f;
//			
//			adjustedX /= 2;
//			adjustedY /= 2;
//			
//			position.x += adjustedY * MAX_HORIZONTAL_SPEED * delta;
//			position.y += -adjustedX * MAX_VERTICAL_SPEED * delta;		
		}
		
		if (Gdx.input.isKeyPressed(Input.Keys.UP)) acceleration.y = MAX_ACCELERATION;
		else if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) acceleration.y = -MAX_ACCELERATION;
		else acceleration.y = 0;
		if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) acceleration.x = -MAX_ACCELERATION;
		else if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) acceleration.x = MAX_ACCELERATION;
		else acceleration.x = 0;
		//acceleration.mul(delta);
		
		if (acceleration.x == 0f && velocity.x != 0f) {
			if (velocity.x > 0) {
				acceleration.x = -MAX_DECELERATION;
				if (velocity.x - acceleration.x < 0) {
					acceleration.x = -(acceleration.x - velocity.x);
				}
			}
			else if (velocity.x < 0){
				acceleration.x = MAX_DECELERATION;
				if (velocity.x + acceleration.x > 0) {
					acceleration.x = (acceleration.x - velocity.x);
				}
			}
		}
		if (acceleration.y == 0f && velocity.y != 0f) {
			if (velocity.y > 0) {
				acceleration.y = -MAX_DECELERATION;
				if (velocity.y - acceleration.y < 0) {
					acceleration.y = -(acceleration.y - velocity.y);
				}
			}
			else if (velocity.y < 0){
				acceleration.y = MAX_DECELERATION;
				if (velocity.y + acceleration.y > 0) {
					acceleration.y = (acceleration.y - velocity.y);
				}
			}
		}
		
		velocity.add(acceleration);
		if (velocity.x > MAX_SPEED) velocity.x = MAX_SPEED;
		if (velocity.x < -MAX_SPEED) velocity.x = -MAX_SPEED;
		if (velocity.x > MAX_SPEED) velocity.x = MAX_SPEED;
		if (velocity.x < -MAX_SPEED) velocity.x = -MAX_SPEED;
		
		position.add(velocity.x * delta, velocity.y * delta);
		
		if (position.x<0) {
			position.x = 0;
			velocity.x = 0;
		}
		if (position.y<0) {
			position.y = 0;
			velocity.y = 0;
		}
		if (position.x > getStage().getWidth() - getWidth()) {
			position.x = getStage().getWidth() - getWidth();
			velocity.x = 0;
		}
		if (position.y > getStage().getHeight() - getHeight()) {
			position.y = getStage().getHeight() - getHeight();
			velocity.y = 0;
		}
		
		setX(position.x);
		setY(position.y);
	}
	
	private void tiltShip(float delta) {
		TextureRegion frame;
		
		float vel = Math.abs(velocity.x);
		
		frame = tiltAnimation.getKeyFrame(tiltAnimation.animationDuration * vel / MAX_SPEED); 
		Gdx.app.log(TAG, tiltAnimation.animationDuration + " " + vel / MAX_SPEED + " " + (tiltAnimation.animationDuration * vel / MAX_SPEED));
		
		if ((velocity.x < 0 && frame.isFlipX()) || 
				(velocity.x > 0 && !frame.isFlipX()))
			frame.flip(true, false);
		
		setDrawable(tiltAnimationDrawables.get(frame));
	}
	
	static final String TAG = Ship2D.class.getSimpleName();
}
